package com.leesche.zcsp.node.web.controller.template;

import java.util.*;

import com.leesche.zcsp.node.utils.security.QEncodeUtil;
import com.leesche.zcsp.node.utils.web.PagingResult;
import com.leesche.zcsp.node.utils.web.SessionManager;
import com.leesche.zcsp.node.utils.web.gernerator.MobileCodeGernerator;
import com.leesche.zcsp.node.utils.web.gernerator.TimeGreaterUilt;
import com.leesche.zcsp.node.utils.web.gernerator.TokenGernerator;
import com.leesche.zcsp.node.utils.web.messge.WebResult;
import com.leesche.zcsp.node.web.model.*;
import com.leesche.zcsp.node.web.service.*;
import com.leesche.zcsp.node.web.service.impl.data.read.QuerySysRoleCondition;
import com.leesche.zcsp.node.web.service.privilege.PrivilegeService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.leesche.zcsp.node.web.constants.Constants;
import com.leesche.zcsp.node.web.service.impl.data.read.SysRoleDto;
import com.leesche.zcsp.node.web.vo.Principal;

public class UserTemplate extends AccessTemplate {

    private final static Logger logger = Logger
            .getLogger(UserTemplate.class.getName());

    @Autowired
    protected SysUserService sysUserService;

    @Autowired
    protected SysUserRoleService sysUserRoleService;

    @Autowired
    protected SysRoleService sysRoleService;

    @Autowired
    protected PubDiscountService pubDiscountService;

    @Autowired
    protected PrivilegeService privilegeService;

    @Autowired
    protected SysUserTokenService sysUserTokenService;

    protected boolean verifyResult = false;

    /**
     * @param user 需新增的用户信息
     * @return 新增的用户信息ID
     * @Title: addSysUserInfo
     * @Description: TODO(添加用户信息)
     * @author Jerry Chen
     * @date 2016年10月8日 上午12:48:29
     */
    protected int addSysUserInfo(SysUser user) throws Exception {
        return sysUserService.insertSelective(user);
    }

    /**
     * @param userid 用户ID
     * @return 用户信息
     * @Title: findSysUser 获取用户信息
     * @Description: TODO(根据用户ID获取用户信息)
     * @author Jerry Chen
     * @date 2016年10月8日 上午12:48:36
     */
    protected SysUser findSysUser(Long userid) throws Exception {
        return sysUserService.selectByPrimaryKey(userid);
    }

    /**
     * @param user
     * @return
     * @Title: changePassword
     * @Description: TODO(修改用户登录密码)
     * @author Jerry Chen
     * @date 2016年10月10日 下午6:39:16
     */
    protected int changePassword(SysUser user) throws Exception {
        return sysUserService.changePassword(user);
    }

    /**
     * @param oldPassword 原始密码
     * @param newPassword 新密码
     * @return 修改结果
     * @Title: changeLoginPassword
     * @Description: TODO(修改当前用户的登录密码)
     * @author Jerry
     * @date 2016-10-20 11:38:43
     */
    protected Map<String, Object> changeLoginPassword(String oldPassword, String newPassword) throws Exception {

        if (oldPassword.equals(newPassword)) {
            return WebResult.failure("*原始密码与新密码一致。").infoKey("info").put("failType", 2).toMap();
        }

        SysUser user = findSysUser(privilegeService.getCurrentPrincipal().getUserid());

        if (!QEncodeUtil.md5Encrypt(oldPassword).equals(user.getPassword())) {
            return WebResult.failure("*与原始密码不符。").infoKey("info").put("failType", 3).toMap();
        } else if (QEncodeUtil.md5Encrypt(newPassword).equals(user.getTransferpassword())) {
            return WebResult.failure("*登录密码不能与提现密码一致。").infoKey("info").put("failType", 2).toMap();
        }

        user.setPassword(QEncodeUtil.md5Encrypt(newPassword));

        changePassword(user);

        return WebResult.success().info("修改登录密码成功").toMap();
    }

    /**
     * @param oldPassword 原始提现密码
     * @param newPassword 新提现密码
     * @return 修改结果
     * @Title: changeTransferPassword
     * @Description: TODO(修改当前用户提现密码)
     * @author Jerry
     * @date 2016-10-20 11:51:53
     */
    protected Map<String, Object> changeTransferPassword(String oldPassword, String newPassword) throws Exception {

        if (oldPassword.equals(newPassword)) {
            return WebResult.failure("*原始密码与新密码一致。").toMap();
        }

        SysUser user = findSysUser(privilegeService.getCurrentPrincipal().getUserid());

        if (!QEncodeUtil.md5Encrypt(oldPassword).equals(user.getTransferpassword())) {
            return WebResult.failure("*与原始提现密码不符。").toMap();
        } else if (QEncodeUtil.md5Encrypt(newPassword).equals(user.getPassword())) {
            return WebResult.failure("*提现密码不能与登录密码一致。").toMap();
        }

        user.setTransferpassword(QEncodeUtil.md5Encrypt(newPassword));

        sysUserService.changeTransferPassword(user);

        return WebResult.success().info("修改提现密码成功").toMap();
    }

    /**
     * @param userid 用户ID
     * @return 用户的角色集合
     * @Title: findUserRole
     * @Description: TODO(获取用户的角色)
     * @author Jerry Chen
     * @date 2016年10月11日 下午8:31:04
     */
    protected List<SysRoleDto> findUserRole(Long userid) {
        return sysUserRoleService.findUserRoleByUserid(userid);
    }

    /**
     * @param condition 查询条件模版
     * @Title: getSysRoleDtoPagingResult
     * @Description: TODO(获取当前用户的子账户角色)
     * @author Jerry
     * @date 2016-10-19 09:49:25
     */
    protected PagingResult<SysRoleDto> getSysRoleDtoPagingResult(QuerySysRoleCondition condition) {
        Principal pc = privilegeService.getCurrentPrincipal();
        if (pc.getNtype() == 1) {
            if (pc.getUserid() != pc.getParentid()) {
                condition.setGeneralAdmin(true);
            }
        } else {
            List<SysRoleDto> sysRoleDtos = this.findUserRole(privilegeService.getCurrentPrincipal().getUserid());

            int size = sysRoleDtos.size();

            condition.setRoleid(new Long[size]);

            for (int i = 0; i < size; i++) {
                condition.getRoleid()[i] = Long.valueOf(sysRoleDtos.get(i)
                        .getRoleid());
            }
        }

        return sysRoleService.findAllByPage(condition);
    }


    /**
     * @param roleids 角色ID集合
     * @param userid  用户ID
     * @param adminid 操作人ID
     * @return 操作结果
     * @Title: addUserRole
     * @Description: TODO(当个用户分配角色)
     * @author Jerry Chen
     * @date 2016年10月11日 下午6:29:01
     */
    protected int addUserRole(Long[] roleids, Long userid, Long adminid) {
        List<SysUserRole> sysUserRoles = new ArrayList<SysUserRole>();
        Date updatetime = new Date();
        for (Long roleid : roleids) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setAdminid(adminid);
            sysUserRole.setUpdatetime(updatetime);
            sysUserRole.setRoleid(roleid);
            sysUserRole.setUserid(userid);
            sysUserRoles.add(sysUserRole);
        }
        return sysUserRoleService.setupUserRole(sysUserRoles);
    }

    /**
     * @param parentUser 父级用户
     *                   父级用户
     * @return 设置结果
     * @throws Exception
     * @Title: setupUserRole
     * @Description: TODO(自动设置设置用户角色)
     * @author Jerry Chen
     * @date 2016年10月8日 下午5:54:27
     */
    protected int setupUserRoleBatch(SysUser parentUser) throws Exception {

        List<SysUser> users = sysUserService.findChildUsers(parentUser);

        users.add(parentUser);

        List<SysRole> roles = sysRoleService.findSysUserRole(users);

        List<SysUserRole> sysUserRoles = new ArrayList<SysUserRole>();
        Date nowTime = new Date();

        for (SysRole sysRole : roles) {
            for (SysUser sysUser : users) {

                if (sysUser.getNtype() == sysRole.getNtype()
                        && sysRole.getIsdefault() == 1) {
                    SysUserRole sysUserRole = new SysUserRole();
                    sysUserRole.setUserid(sysUser.getUserid());
                    sysUserRole.setRoleid(sysRole.getRoleid());
                    sysUserRole.setAdminid(parentUser.getUserid());
                    sysUserRole.setCreatetime(nowTime);
                    sysUserRoles.add(sysUserRole);

                }
            }
        }

        return sysUserRoleService.setupUserRole(sysUserRoles);
    }


    /**
     * @param sysUser 用户信息
     * @param code    短信验证码
     * @Title: createUserInfo(SysUser sysUser, String code)
     * @Description: TODO(创建用户信息)
     * @author Jerry
     * @date 2016-10-18 07:46:03
     */
    protected Map<String, Object> createUserInfo(SysUser sysUser, String code, Integer accessType) throws Exception {

        if (!accessType.equals(Constants.MODULE_TYPE_APP)) {
            Map<String, Object> sessionCodeAndMoblie = verifySeesionCodeAndMoblie();

            if (verifyResult == false) {
                return sessionCodeAndMoblie;
            }

            String sessionCode = sessionCodeAndMoblie.get(Constants.MOBILE_SMS_CODE).toString();
            String sessionMoblie = sessionCodeAndMoblie.get(Constants.MOBILE_NUMBER).toString();

            Map<String, Object> verifyResult = verifyMoblieCode(sysUser.getMobile(), code, sessionCode, sessionMoblie);
            if (verifyResult != null) {
                return verifyResult;
            }
        }

        // 所有商户的父级ID都是超级管理员
        sysUser.setPuserid(1L);
        sysUser.setAdminid(1L);
        // 所有商户的类型都是4
        sysUser.setNtype(4);
        // 所有商户的备注都是“商业用户”
        sysUser.setRemark("商业用户");
        // 所有商户的状态默认都是在用
        sysUser.setState(1);
        // 所有商户只要手机验证码通过，手机验证都是已验证
        sysUser.setMobileconfirmed(1);
        sysUser.setCreatetime(new Date());
        // 所有商户的有效期默认都是3年
        sysUser.setOuttime(TimeGreaterUilt.specifiedTime(Calendar.YEAR, 3));
        sysUser.setPassword(QEncodeUtil.md5Encrypt(sysUser.getPassword()));
        sysUser.setTransferpassword(QEncodeUtil.md5Encrypt(sysUser
                .getTransferpassword()));

        try {
            sysUser = sysUserService.createUser(sysUser, pubDiscountService);
            if (sysUser != null) {
                if (accessType.equals(Constants.MODULE_TYPE_APP)) {
                    SysUserToken userToken = new SysUserToken();
                    TokenGernerator.setupUserToken(userToken, sysUser.getUserid());
                    sysUserTokenService.insertSelective(userToken);
                    //设置为登录状态
                    super.savePrincipalLoginState(accessType, sysUser,userToken.getToken());
                    return WebResult.success().put("data", userToken.getToken()).toMap();
                } else {
                    super.savePrincipalLoginState(accessType, sysUser);
                    return WebResult.success().info("账户注册成功，请完善个人信息。").toMap();
                }
            }
            return WebResult.failure("账户注册失败，请稍后重试。").toMap();
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return WebResult.failure("网络异常导致注册失败，请稍后重试。").toMap();
        }

    }

    /**
     * @param moblie 收短信的手机
     * @param code   短信验证码
     * @return 验证结果 为空则表示通过
     * @Title: verifyMoblieCode
     * @Description: TODO(验证手机短信码和接收短信的手机)
     * @author Jerry
     * @date 2016-10-20 07:48:44
     */
    protected Map<String, Object> verifyMoblieCode(String moblie, String code, String sessionCode, String sessionMoblie) throws Exception {

        if (!code.equals(sessionCode)) {

            return WebResult.failure("*验证码无效，请输入正确的验证码").put("failType", 1).infoKey("info").toMap();

        } else if (!moblie.equals(sessionMoblie)) {

            return WebResult.failure("*请输入接收短信验证码的手机号码").put("failType", 1).infoKey("info").toMap();
        }
        return null;
    }

    /**
     * @return 验证结果
     * @Title: verifySeesionCodeAndMoblie
     * @Description: TODO(验证Session中的验证码)
     * @author Jerry
     * @date 2016-10-21 02:41:09
     */
    protected Map<String, Object> verifySeesionCode() {

        Object sessionCode = SessionManager.getSessionAttribute(Constants.MOBILE_SMS_CODE);
        if (sessionCode == null) {
            verifyResult = false;
            return WebResult.failure("*短信已过期，请重新获取短信。").put("failType", 1).infoKey("info").toMap();
        } else {
            Map<String, Object> sessionCodeAndMoblie = new HashMap<String, Object>();
            verifyResult = true;
            sessionCodeAndMoblie.put(Constants.MOBILE_SMS_CODE, sessionCode.toString());
            return sessionCodeAndMoblie;
        }
    }

    /**
     * @return 验证结果
     * @Title: verifySeesionCodeAndMoblie
     * @Description: TODO(验证Session中的验证码和手机号)
     * @author Jerry
     * @date 2016-10-21 02:41:09
     */
    protected Map<String, Object> verifySeesionCodeAndMoblie() {

        Object sessionCode = SessionManager.getSessionAttribute(Constants.MOBILE_SMS_CODE);
        Object sessionMoblieNumber = SessionManager.getSessionAttribute(Constants.MOBILE_NUMBER);

        if (sessionCode == null || sessionMoblieNumber == null) {
            verifyResult = false;
            return WebResult.failure("*短信已过期，请重新获取短信。").put("failType", 1).infoKey("info").toMap();
        } else {
            Map<String, Object> sessionCodeAndMoblie = new HashMap<String, Object>();
            verifyResult = true;
            sessionCodeAndMoblie.put(Constants.MOBILE_SMS_CODE, sessionCode);
            sessionCodeAndMoblie.put(Constants.MOBILE_NUMBER, sessionMoblieNumber);
            return sessionCodeAndMoblie;
        }
    }

    /**
     * @param vaildatorValue 邮箱、用户或手机号码
     * @return （true:存在/false：不存在）
     * @Title: vaildUser
     * @Description: TODO(验证邮箱、用户、手机号码是否存在)
     * @author 陈立勇
     */
    @ResponseBody
    @RequestMapping(value = "/vaildUserInfo", method = RequestMethod.GET)
    protected Map<String, Boolean> vaildUser(final String vaildatorValue) {

        Map<String, Boolean> vaildatorResult = new HashMap<String, Boolean>();

        SysUserCriteria criteria = new SysUserCriteria();
        criteria.or().andEmailEqualTo(vaildatorValue);
        criteria.or().andUsernameEqualTo(vaildatorValue);
        criteria.or().andMobileEqualTo(vaildatorValue);

        List<Map<String, Object>> result = sysUserService
                .selectByCriteria(criteria);
        if (result.size() > 0) {
            vaildatorResult.put("vaildatorResult", true);
        } else {
            vaildatorResult.put("vaildatorResult", false);
        }

        return vaildatorResult;
    }


}
